/**
 *******************************************************************************
 * @file  gpio/gpio_output/source/main.c
 * @brief Main program of GPIO for the Device Driver Library.
 @verbatim
   Change Logs:
   Date             Author          Notes
   2019-06-24       Zhangxl         First version
 @endverbatim
 *******************************************************************************
 * Copyright (C) 2016, Huada Semiconductor Co., Ltd. All rights reserved.
 *
 * This software is owned and published by:
 * Huada Semiconductor Co., Ltd. ("HDSC").
 *
 * BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
 * BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
 *
 * This software contains source code for use with HDSC
 * components. This software is licensed by HDSC to be adapted only
 * for use in systems utilizing HDSC components. HDSC shall not be
 * responsible for misuse or illegal use of this software for devices not
 * supported herein. HDSC is providing this software "AS IS" and will
 * not be responsible for issues arising from incorrect user implementation
 * of the software.
 *
 * Disclaimer:
 * HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
 * REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
 * ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
 * WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
 * WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
 * WARRANTY OF NONINFRINGEMENT.
 * HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
 * NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
 * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
 * LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
 * INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
 * SAVINGS OR PROFITS,
 * EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 * YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
 * INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
 * FROM, THE SOFTWARE.
 *
 * This software may be replicated in part or whole for the licensed use,
 * with the restriction that this Disclaimer and Copyright notice must be
 * included with each copy of this software, whether used in part or whole,
 * at all times.
 *******************************************************************************
 */

/*******************************************************************************
 * Include files
 ******************************************************************************/
#include "hc32_ddl.h"
#include "modem.h"

/**
 * @addtogroup HC32M120_DDL_Examples
 * @{
 */

/**
 * @addtogroup GPIO_OUTPUT
 * @{
 */

/*******************************************************************************
 * Local type definitions ('typedef')
 ******************************************************************************/

/*******************************************************************************
 * Local pre-processor symbols/macros ('#define')
 ******************************************************************************/
#define LED_R_PORT                      (GPIO_PORT_12)
#define LED_G_PORT                      (GPIO_PORT_7)
#define LED_B_PORT                      (GPIO_PORT_3)

#define LED_R_PIN                       (GPIO_PIN_0)
#define LED_G_PIN                       (GPIO_PIN_0)
#define LED_B_PIN                       (GPIO_PIN_1)

#define LED_R_OFF()                     (GPIO_SetPins(LED_R_PORT, LED_R_PIN))
#define LED_G_OFF()                     (GPIO_SetPins(LED_G_PORT, LED_G_PIN))
#define LED_B_OFF()                     (GPIO_SetPins(LED_B_PORT, LED_B_PIN))

#define LED_R_TOGGLE()                  (GPIO_TogglePins(LED_R_PORT, LED_R_PIN))
#define LED_G_TOGGLE()                  (GPIO_TogglePins(LED_G_PORT, LED_G_PIN))
#define LED_B_TOGGLE()                  (GPIO_TogglePins(LED_B_PORT, LED_B_PIN))

/* SW2 */
#define SW2_PORT                        (GPIO_PORT_2)
#define SW2_PIN                         (GPIO_PIN_1)
#define SW2_EXINT_CH                    (EXINT_CH01)
#define SW2_EXINT_IRQn                  (EXINT01_IRQn)

/*******************************************************************************
 * Global variable definitions (declared in header file with 'extern')
 ******************************************************************************/

/*******************************************************************************
 * Local function prototypes ('static')
 ******************************************************************************/

/*******************************************************************************
 * Local variable definitions ('static')
 ******************************************************************************/
static uint8_t u8ExtIntFlag = 1U, u8LedState = 0U;
static uint16_t u16TickValue = 0U;

/*******************************************************************************
 * Function implementation - global ('extern') and local ('static')
 ******************************************************************************/
/**
 * @brief  SysTick interrupt callback function.
 * @param  None
 * @retval None
 */
void SysTick_IrqHandler(void)
{
    SysTick_IncTick();
    if (0U != u8ExtIntFlag)
    {
        if (++u16TickValue >= 100U)
        {
            u16TickValue = 0U;
            switch (++u8LedState)
            {
                case 1u: LED_R_TOGGLE(); break;
                case 2u: LED_G_TOGGLE(); break;
                case 3u: LED_B_TOGGLE(); break;
                default: u8LedState = 0U; break;
            }
        }
    }
}

/**
 * @brief  SW2 interrupt callback function.
 * @param  None
 * @retval None
 */
void EXINT01_Handler(void)
{
    u8ExtIntFlag = !u8ExtIntFlag;
    if (0u == u8ExtIntFlag)
    {
        u16TickValue = 0u;
        u8LedState = 0u;
        LED_R_OFF();
        LED_G_OFF();
        LED_B_OFF();

    }
    EXINT_ClrExIntSrc(SW2_EXINT_CH);
}

/**
 * @brief  Configure CRC.
 * @param  None
 * @retval None
 */
void CRC_Config(void)
{
    CLK_FcgPeriphClockCmd(CLK_FCG_CRC, Enable);
}

/**
 * @brief  Configure USART.
 * @param  None
 * @retval None
 */
void USART_Config(void)
{
    const stc_uart_init_t stcUartInit = {
        .u32Baudrate         = USART_BAUDRATE,
        .u32BitDirection     = USART_LSB,
        .u32StopBit          = USART_STOP_BITS_1,
        .u32Parity           = USART_PARITY_NONE,
        .u32DataWidth        = USART_DATA_WIDTH_BITS_8,
        .u32ClkMode          = USART_INTCLK_NONE_OUTPUT,
        .u32OversamplingBits = USART_OVERSAMPLING_BITS_8,
        .u32NoiseFilterState = USART_NOISE_FILTER_DISABLE,
        .u32SbDetectPolarity = USART_SB_DETECT_FALLING,
    };

    /* Configure USART RX/TX pin. */
    GPIO_SetFunc(USART_RX_PORT, USART_RX_PIN, USART_RX_FUNC);
    GPIO_SetFunc(USART_TX_PORT, USART_TX_PIN, USART_TX_FUNC);

    /* Enable peripheral clock */
    CLK_FcgPeriphClockCmd(USART_UNIT_CLOCK, Enable);
    /* Initialize USART function. */
    USART_UartInit(USART_UNIT, &stcUartInit);
    /* Enable RX/TX function */
    USART_FuncCmd(USART_UNIT, (USART_RX | USART_TX), Enable);
}

/**
 * @brief  Configure SW2.
 * @param  None
 * @retval None
 */
void SW2_Config(void)
{
    stc_gpio_init_t stcGpioInit;
    stc_exint_config_t stcExIntInit;

    /* Configure structure initialization */
    GPIO_StructInit(&stcGpioInit);
    EXINT_StructInit(&stcExIntInit);
    /* External interrupt SW2 initialize */
    stcGpioInit.u16ExInt = PIN_EXINT_ON;
    GPIO_Init(SW2_PORT, SW2_PIN, &stcGpioInit);
    /* EXINT Channel (SW2) configure */
    stcExIntInit.u16ExIntCh     = SW2_EXINT_CH;
    stcExIntInit.u8ExIntFE      = EXINT_FILTER_ON;
    stcExIntInit.u8ExIntFClk    = EXINT_FCLK_HCLK_DIV8;
    stcExIntInit.u8ExIntLvl     = EXINT_TRIGGER_FALLING;
    EXINT_Init(&stcExIntInit);
    /* NVIC configure */
    NVIC_ClearPendingIRQ(SW2_EXINT_IRQn);
    NVIC_SetPriority(SW2_EXINT_IRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_EnableIRQ(SW2_EXINT_IRQn);
}

/**
 * @brief  Configure system clock.
 * @param  None
 * @retval None
 */
void SysClock_Config(void)
{
    /* Configure the system clock to HRC32MHz. */
    CLK_HRCInit(CLK_HRC_ON, CLK_HRCFREQ_32);
}

/**
 * @brief  Configure LED.
 * @param  None
 * @retval None
 */
void LED_Config(void)
{
    stc_gpio_init_t stcGpioInit;

    GPIO_StructInit(&stcGpioInit);
    /* Reset all LED pin to default */
    GPIO_Init(LED_R_PORT, LED_R_PIN, &stcGpioInit);
    GPIO_Init(LED_G_PORT, LED_G_PIN, &stcGpioInit);
    GPIO_Init(LED_B_PORT, LED_B_PIN, &stcGpioInit);

    /* "Turn off" LED before set to output */
    LED_R_OFF();
    LED_G_OFF();
    LED_B_OFF();
    /* Output enable */
    GPIO_OE(LED_R_PORT, LED_R_PIN, Enable);
    GPIO_OE(LED_G_PORT, LED_G_PIN, Enable);
    GPIO_OE(LED_B_PORT, LED_B_PIN, Enable);
}

/**
 * @brief  Main function of GPIO project
 * @param  None
 * @retval int32_t return value, if needed
 */
int32_t main(void)
{
    /* Peripheral configuration */
    SysClock_Config();
    USART_Config();
    CRC_Config();
    LED_Config();
    SW2_Config();
    /* SysTick configuration */
    SysTick_Init(1000u);

    while (1)
    {
        Modem_Process(1000);
    }
}

/**
 * @}
 */

/**
 * @}
 */

/*******************************************************************************
 * EOF (not truncated)
 ******************************************************************************/
